home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
utility
/
uwserver.zip
/
uwserver.tar
/
misc
/
macmouse.el
< prev
next >
Wrap
Lisp/Scheme
|
1991-01-25
|
9KB
|
272 lines
;;; macmouse.el (Version: 2.0)
;;; Copyright (C) Gregory S. Lauer (glauer@bbn), 1985.
;;; Please send suggestions and corrections to the above address.
;;;
;;; This file contains macmouse, a GNU Emacs mouse package for UW.
;;
;; GNU Emacs is distributed in the hope that it will be useful,
;; but without any warranty. No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing.
;; Everyone is granted permission to copy, modify and redistribute
;; GNU Emacs, but only under the conditions described in the
;; document "GNU Emacs copying permission notice". An exact copy
;; of the document is supposed to have been given to you along with
;; GNU Emacs so that you can know how you may redistribute it all.
;; It should be in a file named COPYING. Among other things, the
;; copyright notice and this notice must be preserved on all copies.
;;; Original version for Gosling emacs by Chris Kent, Purdue University 1985.
;;; Modified by Gregory Lauer, BBN, Novemeber 1985.
;
;
;
; Macmouse provides the following features:
; Up or down mouse button in a window selects that window
;
; A scroll bar/thumbing area for each window with the following features:
; the mode lines are horizontal scroll bars
; (running from rightmost column to under leftmost column)
; the unused right window bar and the dividing lines between
; windows are vertical scroll bars
; (running from top of window THRU modeline
; for vertical scroll bars:
; click at line 1 does previous page
; click at last line does next page
; click anywhere else "thumbs" to the relative portion of the buffer.
; shift-click at line 1 scrolls one line down
; shift-click at last line scrolls one line up
; shift-click elsewhere moves line to top of window
; option-shift-click elsewhere moves line to bottom of window
; for horizontal scroll bars:
; click at column 1 does scroll right one window width
; click at last column does scroll left one window width
; click anywhere else moves to that "percent" of the buffer width
; shift-click at column 1 scrolls one column right
; shift-click at last column scrolls one column left
; shift-click elsewhere moves column to right of window
; option-shift-click elsewhere moves column to left of window
;
; There is also basic positioning and kill-buffer support:
; click in a buffer moves dot there and selects that buffer
; drag copies the dragged region to the kill buffer
; shift-drag deletes the dragged region to the kill buffer
;
; It is possible to use the scrolling and thumbing area to make the region
; larger than a single screen; just click, scroll, release. Make sure
; that the last scroll is just a down event; the up must be in the buffer.
; The last mouse position is remembered for each different buffer (not
; window), and thus you can start a drag in one buffer, select another,
; go back to the first buffer, etc.
;
; option-click yanks from the kill buffer
; option-shift-click similarly yanks from a named buffer.
;
(defconst mouse-max-x 95 "Maximum UW column returned on mouse click")
(defconst mouse-max-y 95 "Maximum UW row returned on mouse click")
(make-variable-buffer-local 'mouse-last-x) ; x of last event
(set-default 'mouse-last-x 0)
(make-variable-buffer-local 'mouse-last-y) ; y of last event
(set-default 'mouse-last-y 0)
(make-variable-buffer-local 'mouse-last-b) ; buttons at last event
(set-default 'mouse-last-b 0)
(make-variable-buffer-local 'mouse-last-dot) ; dot after last event
(set-default 'mouse-last-dot 0)
(make-variable-buffer-local 'scrolling-p)
(set-default 'scrolling-p nil)
(defun move-mac-cursor ()
(interactive)
(let (savest b x y up down lock shift option command)
(setq savest stack-trace-on-error)
(setq stack-trace-on-error nil)
; decode everything
(setq y (- (read-char) 32))
(setq x (- (read-char) 32))
(setq b (- (read-char) 32))
(setq command (< 0 (logand b 1))) ; command key
(setq shift (< 0 (logand b 2))) ; shift
(setq lock (< 0 (logand b 4))) ; caps-lock
(setq option (< 0 (logand b 8))) ; option
(setq down (< 0 (logand b 16))) ; mouse down
(setq up (< 0 (logand b 32))) ; mouse up
(condition-case ()
(progn
(select-window-containing-x-and-y x y) ; side-effect sets scrolling-p
(if scrolling-p
(mouse-scroll-region b x y)
(progn
(move-to-window-x-y x y) ; move cursor to mouse-dot always
(if down (setq mouse-last-dot (dot)))
(mouse-edit-action))))
(error (message "Click not in selectable window")
(sit-for 1)
(message "")))
(setq stack-trace-on-error savest)
(if down
(progn
(setq mouse-last-x x)
(setq mouse-last-y y)
(setq mouse-last-b b))
(progn
(setq mouse-last-x 0)
(setq mouse-last-y 0)
(setq mouse-last-b 0)))))
(defun mouse-edit-action ()
;marking and editing actions on buttons:
; if no movement, nothing.
; if movement, save mouse-last-dot,
; and edit.
; editing (on upstrokes):
; unmodified, copy to kill buffer.
; SHIFTed, delete (cut) to kill buffer.
;
; option-click yanks from kill buffer;
; shift-option-click from named buffer.
(let ((fun (get 'mouse-function b)))
(if fun (apply fun nil))))
; individual button bindings
; generally will only need up mouse button: mouse-last-dot
; is saved automatically on down mouse button
; only need to define functions for keys that get used
(put 'mouse-function 32 ; up
'(lambda ()
(if (and (not (mouse-click-p))
(not scrolling-p))
(copy-region-as-kill (dot) mouse-last-dot))))
(put 'mouse-function 34 ; up/shift
'(lambda ()
(if (and (not (mouse-click-p))
(not scrolling-p))
(kill-region (dot) mouse-last-dot))))
(put 'mouse-function 40 ; up/option
'(lambda ()
(if (mouse-click-p)
(progn
(yank)
(exchange-dot-and-mark)))))
(put 'mouse-function 42
'(lambda () ; up/option/shift
(if (mouse-click-p)
(insert-buffer (read-buffer "Insert contents of buffer: ")))))
(defun mouse-click-p ()
(= (dot) mouse-last-dot))
(defun set-window-boundaries ()
(let ((edges (window-edges)))
(setq xl (1+ (car edges)))
(setq yt (1+ (car (cdr edges))))
(let ((temp (car (cdr (cdr edges)))))
(setq xr (if (= (screen-width) temp) mouse-max-x temp)))
(let ((temp (car (cdr (cdr (cdr edges))))))
(setq yb (if (= (screen-height) temp) mouse-max-y temp )))))
(defun select-window-containing-x-and-y (x y)
(let ((starting-window (selected-window)))
(set-window-boundaries)
(while (not (point-in-window x y))
(other-window 1)
(if (eq (selected-window) starting-window)
(error nil)
(set-window-boundaries)))
(if (or (= x xr) (= y yb))
(setq scrolling-p t)
(setq scrolling-p nil))))
(defun point-in-window (x y)
(and (<= xl x)(<= x xr)(<= yt y)(<= y yb)))
(defun move-to-window-x-y (x y)
(move-to-window-line (- y yt))
(move-to-window-column (- x xl)))
(defun move-to-window-column (x)
(move-to-column (+ (max 0 (- (window-hscroll) 1)) x)))
(defun mouse-scroll-region (b x y)
(if down
(if shift
(do-lines b x y)
(do-pages b x y)))
(if (and up
(or (/= x mouse-last-x)
(/= y mouse-last-y)))
(if shift
(do-lines b x y)
(do-pages b x y))))
(defun do-lines (b x y) ; fine control over lines
(if (= x xr)
(cond ((= y yt)(scroll-down 1))
((= y yb)(scroll-up 1))
(t (if option
(scroll-down (- yb y 1))
(scroll-up (- y yt))))))
(if (and (= y yb) (/= x xr))
(cond ((<= x xl)(scroll-right 1))
((>= x (1- xr))(scroll-left 1))
(t (if option
(move-column-right x)
(move-column-left x))))))
(defun move-column-left (x) ;need to mess about a bit because
(scroll-left ;first scroll left of 1 just writes
(if (= (window-hscroll) 0) ;a column of $s in column 1
(- x xl)
(- x xl 1))))
(defun move-column-right (x)
(scroll-right (- xr x 2)))
(defun do-pages (b x y) ; large motions via pages and thumbing
(if (= x xr)
(cond ((= y yt)(scroll-down nil))
((= y yb)(scroll-up nil))
(t (goto-percent (/ (* (- y yt 1) 100)
(- yb yt 2))))))
(if (and (= y yb)(/= x xr))
(cond ((<= x xl)(scroll-right (- (window-width)
next-screen-context-lines)))
((>= x (1- xr))(scroll-left (- (window-width)
next-screen-context-lines)))
(t (goto-horizontal-percent (/ (* (- x xl 1) 100)
(- xr xl 2)))))))
(defun goto-percent (p)
(goto-char (/ (* (- (dot-max) (dot-min)) p) 100)))
(defun goto-horizontal-percent (p) ;try to put this percent of columns
(let ((window-offset (window-hscroll));in the center column of the window
delta) ;unless that would move the first or
(setq delta ;last column past the window edge
(- window-offset
(min (max 0 (- (/ (* (screen-width) p) 100)
(/ (- xr xl) 2)))
(- (screen-width) (- xr xl)))))
(scroll-right delta)))
(global-set-key "\em" 'move-mac-cursor)